package com.s3u4.concurrence.forkjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * Created by Captain on 29/03/2018.
 */
public class CountTask extends RecursiveTask<Long> {


    private static final int THRESHOLD = 10000;
    private long start;
    private long end;

    public CountTask(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    public Long compute() {
        System.out.println(Thread.currentThread().getId() + " compute : " + start + " , " + end);
        long sum = 0;
        boolean canCompute = (end - start) < THRESHOLD;
        if ( canCompute ){
            for (long i = start; i <= end ; i++) {
                sum += i;
            }
        } else {
            // 分成10个小任务
            long step = (end + start) / 100;
            List<CountTask> subTasks = new ArrayList<>();
            long position = start;
            for (int i = 0 ;i < 100 ;i++){
                long lastOne = position + step;
                if ( lastOne > end ) {
                    lastOne = end;
                }
                CountTask subTask = new CountTask(position,lastOne);
                position += step + 1;
                subTasks.add(subTask);
                subTask.fork();
            }
            for ( CountTask task : subTasks ){
                sum += task.join();
            }
        }
        return sum;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        CountTask countTask = new CountTask(0,200000);
        ForkJoinTask<Long> fkTask = forkJoinPool.submit(countTask);

        Long result = fkTask.get();
        System.out.println(result);

        forkJoinPool.shutdown();
    }



}
